package com.kuangstudy.service.focus;

import com.kuangstudy.constant.RedisConstants;
import com.kuangstudy.entity.User;
import com.kuangstudy.mapper.UserMapper;
import com.kuangstudy.utils.bean.BeanMapUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author panghu
 * @version 1.0.0
 * @createTime 2023年09月18日 19:58:00
 * @Description 关注取关业务
 */
@Service
@Slf4j
public class AttentionService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     * 粉丝关注业务：我关注了飞哥
     *
     * @param userId   我
     * @param followId 飞哥
     */
    public String follow(Long userId, Long followId) {
        // 1、获取redis操作set的句柄对象
        SetOperations<String, Long> setOperations = redisTemplate.opsForSet();
        // 2、在飞哥的粉丝列表中直接添加我
        setOperations.add(RedisConstants.USER_FANS_LIST_SET + followId, userId);
        // 3、在我的关注列表中添加飞哥
        setOperations.add(RedisConstants.USER_FOCUS_LIST_SET + userId, followId);
        return "success";
    }

    /**
     * 查询我的关注列表
     *
     * @param userId 用户id
     */
    public List<User> selectMyFocusList(Long userId) {
        SetOperations<String, Long> setOperations = redisTemplate.opsForSet();
        // 通过  smembers userId  把set集合中所有的数据查询出来
        Set<Long> members = setOperations.members(RedisConstants.USER_FOCUS_LIST_SET + userId);
        List<User> userList = getUserInfo(members);
        return userList;
    }

    /**
     * 查询我的粉丝列表
     *
     * @param userId 用户id
     */
    public List<User> selectMyFansList(Long userId) {
        SetOperations<String, Long> setOperations = redisTemplate.opsForSet();
        // 通过  smembers userId  把set集合中所有的数据查询出来
        Set<Long> members = setOperations.members(RedisConstants.USER_FANS_LIST_SET + userId);
        List<User> userList = getUserInfo(members);
        return userList;
    }


    /**
     * 粉丝关注业务：我取消关注了飞哥
     *
     * @param userId   我
     * @param followId 飞哥
     */
    public String unFollow(Long userId, Long followId) {
        // 1、获取redis操作set的句柄对象
        SetOperations<String, Long> setOperations = redisTemplate.opsForSet();
        // 2、在飞哥的粉丝列表中直接添加我
        setOperations.remove(RedisConstants.USER_FANS_LIST_SET + followId, userId);
        // 3、在我的关注列表中添加飞哥
        setOperations.remove(RedisConstants.USER_FOCUS_LIST_SET + userId, followId);
        return "success";
    }


    /**
     * 把set和hash结合出来
     *
     * @param userIdsInfo
     * @return
     */
    public List<User> getUserInfo(Set<Long> userIdsInfo) {
        // 1：创建用户集合
        List<User> userList = new ArrayList<>();

        // 2: 需要从hash去获取的属性
        List<String> filedList = new ArrayList<>();
        filedList.add("id"); //listMap.get(0)
        filedList.add("nickName"); //listMap.get(1)
        filedList.add("password"); //listMap.get(2)
        filedList.add("sex"); //listMap.get(3)
        filedList.add("status"); //listMap.get(4)
        filedList.add("createTime"); //listMap.get(5)
        filedList.add("updateTime"); //listMap.get(6)

        // 2：循环关注列表or粉丝列表的用户id进行获取
        for (Long userId : userIdsInfo) {
            // 3：获取用户在hash中的注册完整信息对应的key
            String hKey = RedisConstants.REG_USER_HASH + userId;
            // 4: 把 reg:user:hash:1 的信息从hash数据结构中取出来，获取id，nickName属性
            List<Object> listMap = redisTemplate.opsForHash().multiGet(hKey, filedList);
            // 5：如果在缓存中没有找到对应的用户信息
            if (listMap.get(0) == null && listMap.get(1) == null) {
                // 6: 从数据库中根据userId查询用户新消息
                User user = this.getUserDbCache(userId);
                userList.add(user);
            } else {
                User user = new User();
                user.setId(Long.parseLong(listMap.get(0).toString()));
                user.setNickName(listMap.get(1).toString());
                user.setPassword(listMap.get(2).toString());
                user.setSex((Integer)listMap.get(3));
                user.setStatus((Integer) listMap.get(4));
                user.setCreateTime((Date) listMap.get(5));
                user.setUpdateTime((Date) listMap.get(6));
                userList.add(user);
            }
        }
        return userList;
    }

    /**
     * 从数据库中查询用户的信息
     *
     * @param userId
     * @return
     */
    public User getUserDbCache(Long userId) {
        // 1： 然后查询最新的用户信息放入到redis的hash重
        User user = userMapper.selectById(userId);
        // 2: 准备用存入的key，将用户信息存入到redis的hash中
        String key = RedisConstants.REG_USER_HASH + userId;
        Map<String, Object> map = BeanMapUtils.beanToMap(user);
        redisTemplate.opsForHash().putAll(key, map);
        // 3: 设置key的失效时间一个月
        redisTemplate.expire(key, 30, TimeUnit.DAYS);
        return user;
    }


}
